package com.itlong.cloud.sdk.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.itlong.cloud.POJO.DTO.sdk.QrCodeSDKDTO;
import com.itlong.cloud.POJO.DTO.sdk.QrCodeSDKPermissionDTO;
import com.itlong.cloud.POJO.DTO.sdk.QrcodeSDKGetPassRecordDTO;
import com.itlong.cloud.POJO.VO.sdk.QrcodeSDKGetPassRecordVO;
import com.itlong.cloud.enumerate.AppQrcodeProtocolVersionEnum;
import com.itlong.cloud.sdk.dao.IQrCodeSDKDao;
import com.itlong.cloud.sdk.service.IQrCodeSDKService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.security.NoSuchProviderException;
import java.util.HashMap;
import java.util.Map;

/**
 * <desc>
 *      二维码SDK 业务处理接口实现类
 * </desc>
 *
 * @createDate 2018/05/24
 */
@Service
public class QrCodeSDKServiceImpl implements IQrCodeSDKService{

    private static Logger LOG = LoggerFactory.getLogger(QrCodeSDKServiceImpl.class);

    @Autowired
    IQrCodeSDKDao iQrCodeSDKDao;

    /**
     * <desc>
     *      获取二维码字符串
     * </desc>
     *
     * @param qrCode 二维码所需数据json字符串
     * @return
     * @author Jiaqi.X
     * @createDate 2018/05/24
     */
    @Override
    public Map<String,Object> secretQrCodeStr(String qrCode) throws Exception {
        QrCodeSDKDTO qrCodeSDKDTO = JsonUtil.decode(qrCode, new TypeReference<QrCodeSDKDTO>() {});
        StringBuilder qrCodeStr = new StringBuilder("01");   //初始化协议版本
        Map<String,Object> result = new HashMap<>();
//        String projectId=null;
        String vi = ""; //加密向量
        //类型 访客为44 业主为43 物业为42
        if(qrCodeSDKDTO.getType().equals("1")){
            qrCodeStr.append("43");
        }else if(qrCodeSDKDTO.getType().equals("2")){
            qrCodeStr.append("44");
        }else if (qrCodeSDKDTO.getType().equals("3")) {
            qrCodeStr.append("42");
        } else {
            result.put("secretQrcode", 1);
            return result;  //二维码类型错误
        }
        //项目id解密
//        try {
//            projectId = DesEncryptUtil.projectIdDesEncrypt(qrCodeSDKDTO.getProjectId());
//        }catch (Exception e){
//            result.put("secretQrcode",2);
//            return result; //项目id错误
//        }
        String projectKey = iQrCodeSDKDao.getProjectKey(qrCodeSDKDTO.getProjectId());
        String key = DesEncryptUtil.getUserKey(qrCodeSDKDTO.getUserId()+"00000000",projectKey);
        //用户唯一识别码
        qrCodeStr.append("04" + qrCodeSDKDTO.getUserId());
        //启用时间
        qrCodeStr.append(qrCodeSDKDTO.getBeginDate());
        vi+=qrCodeSDKDTO.getBeginDate();
        //有效时间段
        qrCodeStr.append(StringHandlerUtil.autlSupply(4, Integer.toHexString(Integer.valueOf(qrCodeSDKDTO.getValidityDuration())).toUpperCase(), "0"));
        vi+=StringHandlerUtil.autlSupply(4, Integer.toHexString(Integer.valueOf(qrCodeSDKDTO.getValidityDuration())).toUpperCase(), "0");
        //有效次数
        qrCodeStr.append("01");
        vi+="01";
        //此处处理当权限组数量为255时，则生成二维码有所有设备权限
        if("255".equals(qrCodeSDKDTO.getPermissCount())){
            qrCodeStr.append("FF");
        }else{
            //权限组数量
            qrCodeStr.append(qrCodeSDKDTO.getPermission().size() < 255 ?
                    StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(qrCodeSDKDTO.getPermission().size())).toUpperCase(), "0") : "FF");
        }
        if(qrCodeSDKDTO.getPermission() !=null && qrCodeSDKDTO.getPermission().size() < 255) {
            //权限组
            for (QrCodeSDKPermissionDTO permission : qrCodeSDKDTO.getPermission()) {
                //权限标识
                qrCodeStr.append(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(permission.getPermissionMark())).toUpperCase(), "0"));
                //楼层权限标识 楼层权限
                if (permission.getPermissionType().equals("2")) {
                    qrCodeStr.append("FF");
                    //自动登记楼层
                    if (StringUtils.isBlank(permission.getDirectFloor())) {
                        qrCodeStr.append("00");
                    } else {
                        qrCodeStr.append(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(permission.getDirectFloor())).toUpperCase(), "0"));
                    }
                    continue;
                }
                if(permission.getPermissionType().equals("0")){
                    qrCodeStr.append("00");
                    continue;
                }
                //正常楼层数量
                String[] floor = StringHandlerUtil.splitString(permission.getPermissionFloor());
                if (floor.length < 14) {
                    qrCodeStr.append(StringHandlerUtil.autlSupply(2, Integer.toHexString(floor.length).toUpperCase(), "0"));
                    for (String f : floor) {
                        qrCodeStr.append(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(f)).toUpperCase(), "0"));
                    }
                } else {
                    qrCodeStr.append("F0");
                    qrCodeStr.append(StringHandlerUtil.getQrCodeSDKFloor(permission.getPermissionFloor()));
                }
                //自动登记楼层
                if (StringUtils.isBlank(permission.getDirectFloor())) {
                    qrCodeStr.append("00");
                } else {
                    qrCodeStr.append(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(permission.getDirectFloor())).toUpperCase(), "0"));
                }
            }
        }
        //长度
        qrCodeStr.insert(0,StringHandlerUtil.autlSupply(4, Integer.toHexString(Integer.valueOf((qrCodeStr.length() + 8) / 2)).toUpperCase(), "0"));
        //起始符
        qrCodeStr.insert(0,"574C");
        //计算mac
        qrCodeStr=qrCodeStr.append(DesEncryptUtil.ownerAndVisitorMacEncrypt(vi,key,qrCodeStr.toString()));
        result.put("secretQrcode",qrCodeStr.toString());
//        result.put("userKey",key);
        return result;
    }

    /**
     * <desc>
     *      生成新版sdk二维码
     * </desc>
     *
     * @param qrCode
     * @return
     * @author Jiaqi.X
     * @createDate 2019/10/28
     */
    @Override
    public Map<String, Object> secretNewQrCodeStr(String qrCode) throws IOException, NoSuchProviderException {
        Map<String,Object> result = new HashMap<>();
        QrCodeSDKDTO qrCodeSDKDTO = JsonUtil.decode(qrCode, new TypeReference<QrCodeSDKDTO>() {});
        StringBuilder heard=new StringBuilder("SDK:{L:");
        StringBuilder content = new StringBuilder();
        //协议版本 1Byte, Hex码
        content.append("V:"+ AppQrcodeProtocolVersionEnum.NEW.getType()+",");
        //用户uid
        content.append("U:"+qrCodeSDKDTO.getUserId()+",");
        //类型 访客为44 业主为43 物业为42
        content.append("M:");
        if(qrCodeSDKDTO.getType().equals("1")){
            content.append("53,");
        }else if(qrCodeSDKDTO.getType().equals("2")){
            content.append("54,");
        }else if (qrCodeSDKDTO.getType().equals("3")) {
            content.append("52,");
        } else {
            result.put("secretQrcode", 1);
            return result;  //二维码类型错误
        }
        //房间编号 固定00
        content.append("H:00,");
        //批次号
        content.append("I:"+StringHandlerUtil.autlSupply(4,Integer.toHexString(Integer.valueOf(qrCodeSDKDTO.getBatch())),"0")+",");
        //启用时间
        content.append("T:"+qrCodeSDKDTO.getBeginDate()+",");
        //有效时间段
        String startTime = qrCodeSDKDTO.getBeginDate();
        content.append("P:"+StringHandlerUtil.autlSupply(4, Integer.toHexString(Integer.valueOf(qrCodeSDKDTO.getValidityDuration())).toUpperCase(), "0")+",");
        //有效次数
        String validCount = StringHandlerUtil.autlSupply(4,qrCodeSDKDTO.getValidityTime()!=null ? Integer.toHexString(qrCodeSDKDTO.getValidityTime()) : "01","0").toUpperCase();
        content.append("S:"+validCount+",");
        if(validCount.length()>2){
            validCount=validCount.substring(2,4);
        }
        String value =startTime+StringHandlerUtil.autlSupply(4, Integer.toHexString(Integer.valueOf(qrCodeSDKDTO.getValidityDuration())).toUpperCase(), "0")+validCount;

        if("255".equals(qrCodeSDKDTO.getPermissCount())){
            content.append("Q:{N3:0,X3:0},");
        }else{
            if(qrCodeSDKDTO.getPermission() !=null && qrCodeSDKDTO.getPermission().size() < 255) {
                //权限组
                for (QrCodeSDKPermissionDTO permission : qrCodeSDKDTO.getPermission()) {
                    content.append("Q:{");
                    //权限标识
                    content.append("N1:" + StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(permission.getPermissionMark())).toUpperCase(), "0") + ",");
                    //楼层权限标识 楼层权限
                    if (permission.getPermissionType().equals("2")) {
                        content.append("X3:00,");
                        if (StringUtils.isBlank(permission.getDirectFloor())) {
                            content.append("Y:" + "00");
                        } else {
                            content.append("Y:" + StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(permission.getDirectFloor())).toUpperCase(), "0"));
                        }
                        content.append("},");
                        continue;
                    }
                    if (permission.getPermissionType().equals("0")) {
                        content.append("X2:00,Y:00");
                        content.append("},");
                        continue;
                    }
                    //正常楼层数量
                    String[] floor = StringHandlerUtil.splitString(permission.getPermissionFloor());
                    content.append("X2:" + StringHandlerUtil.assembleNewDeviceNum(floor) + ",");
                    //自动登记楼层
                    if (StringUtils.isBlank(permission.getDirectFloor())) {
                        content.append("Y:" + "00");
                    } else {
                        content.append("Y:" + StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(permission.getDirectFloor())).toUpperCase(), "0"));
                    }
                    content.append("},");
                }
            }
        }

        String projectKey = iQrCodeSDKDao.getProjectKey(qrCodeSDKDTO.getProjectId());
        String key = DesEncryptUtil.getUserKey(qrCodeSDKDTO.getUserId()+"00000000",projectKey);
        //计算mac
        String mac="K:"+DesEncryptUtil.newOwnerAndVisitorMacEncrypt(value, key, content.toString());
        String qrcode = heard.toString()+ StringHandlerUtil.autlSupply(4,Integer.toHexString((content + mac).length()).toUpperCase(),"0") +","+content+mac+"}";
        result.put("secretQrcode",qrcode);
        return result;
    }


    /**
     * <desc>
     *      身份校验
     * </desc>
     *
     * @param appId
     * @param appsecret
     * @param projectId
     * @return
     * @author Jiaqi.X
     * @createDate 2018/10/15
     */
    @Override
    public Integer checkRequestIdentity(String appId, String appsecret, String projectId) {
        return iQrCodeSDKDao.checkRequestIdentity(appId,appsecret,projectId);
    }


    /**
     * <desc>
     *      获取分页数据
     * </desc>
     *
     * @param pageDTO   参数DTO
     * @return
     * @author Jiaqi.X
     * @createDate 2019/06/30
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<QrcodeSDKGetPassRecordVO> getPage(QrcodeSDKGetPassRecordDTO pageDTO) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(pageDTO);
        //分页类默认pageSize为20
        Page<QrcodeSDKGetPassRecordVO> page = new Page<>();
        page.getPage().setPageSize(pageDTO.getPageSize());
        page.getPage().setCurrentPage(pageDTO.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        //填充返回数据集
        long startTime = System.currentTimeMillis();
        page.setRows(iQrCodeSDKDao.getPage(params), iQrCodeSDKDao.getPageCount(params));
        long endTime = System.currentTimeMillis();
        long timeConsuming = endTime - startTime;
        LOG.info("【请求二维码SDK通行记录数据耗时】：" + timeConsuming + "ms,"+"【传参】：deviceType："+pageDTO.getDeviceType()+",projectId:"+pageDTO.getProjectId()
                +",startTime:"+pageDTO.getPassStartTime()+",endTime:"+pageDTO.getPassEndTime()+
                ",currentPage:"+pageDTO.getCurrentPage()+",pageSize:"+pageDTO.getPageSize());
        return page;
    }
}
